package com.xbongbong.saas.help.fund;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormSubDataEntity;
import com.xbongbong.paas.elasticsearch.model.PaasFormSubDataEsModel;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.PaymentSubDataEntity;
import com.xbongbong.saas.model.PaymentModel;
import com.xbongbong.saas.model.PaymentSubDataModel;
import org.elasticsearch.action.support.WriteRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author 吴峰
 * @date 2020/10/15 14:39
 */
@Component
public class PaymentHelp {

    private static final Logger LOGGER = LoggerFactory.getLogger(PaymentHelp.class);

    @Resource
    private PaymentModel paymentModel;
    @Resource
    private PaymentSubDataModel paymentSubDataModel;
    @Resource
    private PaasFormSubDataEsModel paasFormSubDataEsModel;

    @Transactional(rollbackFor = Exception.class)
    public void updateBatch(List<? extends PaasFormDataEntity> paymentList, String corpid, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        if (CollectionsUtil.isEmpty(paymentList)) {
            return;
        }
        Set<String> subAttrSet = new HashSet<>();
        explainMap.forEach((item, value)->{
            if (Objects.equals(FieldTypeEnum.SUB_FORM.getType(), value.getFieldType())) {
                subAttrSet.add(item);
            }
        });
        List<PaymentSubDataEntity> sourcePaymentSubDataList = new ArrayList<>();
        List<PaymentSubDataEntity> updatePaymentSubDataList = new ArrayList<>();
        List<PaymentSubDataEntity> insertPaymentSubDataList = new ArrayList<>();
        Map<Long, Long> paymentSubDataIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        try {
            paymentModel.updateBatchForData(paymentList, corpid);
            if (CollectionsUtil.isNotEmpty(subAttrSet)) {

                Set<Long> parentIdList = new HashSet<>();
                Map<Long, Long> subDataIdList = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                long now = DateTimeUtil.getInt();
                paymentList.forEach(item->{
                    parentIdList.add(item.getId());
                    JSONObject subFormData = item.getSubFormData();
                    subAttrSet.forEach(attr->{
                        JSONArray jsonArray = subFormData.getJSONArray(attr);
                        if (Objects.nonNull(jsonArray)) {
                            for (int i = 0; i < jsonArray.size(); i++) {
                                JSONObject jsonObject = jsonArray.getJSONObject(i);
                                Long subDataId = jsonObject.getLong(BusinessConstant.SUB_DATA_ID);
                                if (Objects.isNull(subDataId)) {
                                    PaymentSubDataEntity paymentSubDataEntity = new PaymentSubDataEntity(item.getFormId(), corpid, item.getId(), attr, jsonObject);
                                    insertPaymentSubDataList.add(paymentSubDataEntity);
                                } else {
                                    subDataIdList.put(subDataId, item.getId());
                                    PaymentSubDataEntity paymentSubDataEntity = new PaymentSubDataEntity();
                                    jsonObject.remove(BusinessConstant.SUB_DATA_ID);
                                    paymentSubDataEntity.setCorpid(corpid);
                                    paymentSubDataEntity.setId(subDataId);
                                    paymentSubDataEntity.setData(jsonObject);
                                    paymentSubDataEntity.setDataId(item.getDataId());
                                    paymentSubDataEntity.setUpdateTime(now);
                                    paymentSubDataEntity.setDel(DelEnum.NORMAL.getDel());
                                    updatePaymentSubDataList.add(paymentSubDataEntity);
                                }
                            }
                        }
                    });
                });
                if (CollectionsUtil.isNotEmpty(parentIdList)) {
                    Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put(StringConstant.CORPID, corpid);
                    param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                    param.put("dataIdIn", parentIdList);
                    List<? extends PaasFormSubDataEntity> paymentSubDataList = paymentSubDataModel.findEntitys(param);
                    if (Objects.nonNull(paymentSubDataList)) {

                        for (PaasFormSubDataEntity item : paymentSubDataList) {
                            if (!subDataIdList.containsKey(item.getId())) {
                                // 前端传来的数据中已经没有了这个id，说明该行子表单数据已被删除
                                paymentSubDataIdMap.put(item.getId(), item.getDataId());
                            }
                        }
                        if (!paymentSubDataIdMap.isEmpty()) {
                            paymentSubDataModel.deleteBatchByIdIn(paymentSubDataIdMap, corpid);
                        }
                    }
                }
                if (CollectionsUtil.isNotEmpty(insertPaymentSubDataList)) {
                    paymentSubDataModel.insertBatch(insertPaymentSubDataList);
                }
                if (CollectionsUtil.isNotEmpty(updatePaymentSubDataList)) {
                    Set<Long> paymentIdList = new HashSet<>();
                    updatePaymentSubDataList.forEach(item->{
                        paymentIdList.add(item.getId());
                    });
                    Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put(StringConstant.CORPID, corpid);
                    param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                    param.put(StringConstant.IDIN, paymentIdList);
                    sourcePaymentSubDataList = paymentSubDataModel.findEntitys(param);

                    paymentSubDataModel.updateBatchByEntity(updatePaymentSubDataList, corpid);
                }
            }
        } catch (Exception e) {
            LOGGER.error("paymentHelp.updateBatch批量保存回款计划出错：", e);
            // 回滚
            rollback(sourcePaymentSubDataList, insertPaymentSubDataList, paymentSubDataIdMap, corpid);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    private void rollback(List<PaymentSubDataEntity> payPlanSheetSubDataList, List<PaymentSubDataEntity> insertPaymentSubDataList,
                          Map<Long, Long> paymentSubDataIdMap, String corpid) {
        try {
            if (CollectionsUtil.isNotEmpty(payPlanSheetSubDataList)) {
                paasFormSubDataEsModel.updateBatchByEntity(payPlanSheetSubDataList, IndexTypeEnum.IDX_SAAS_PAYMENT_SUB, WriteRequest.RefreshPolicy.NONE);
            }
            if (CollectionsUtil.isNotEmpty(insertPaymentSubDataList)) {
                Map<Long, Long> idMap = new HashMap<>(insertPaymentSubDataList.size());
                insertPaymentSubDataList.forEach(item->{
                    idMap.put(item.getId(), item.getDataId());
                });
                paasFormSubDataEsModel.deleteBatchByIdIn(corpid, idMap, IndexTypeEnum.IDX_SAAS_PAYMENT_SUB, WriteRequest.RefreshPolicy.NONE, DelEnum.DELETE);
            }
            if (!paymentSubDataIdMap.isEmpty()) {
                paasFormSubDataEsModel.deleteBatchByIdIn(corpid, paymentSubDataIdMap, IndexTypeEnum.IDX_SAAS_PAYMENT_SUB, WriteRequest.RefreshPolicy.NONE, DelEnum.NORMAL);
            }
        } catch (Exception e) {
            LOGGER.error("paymentHelp.rollback回滚失败：", e);
        }

    }
}
